#!/usr/bin/env python
# 2013-05-09 20:47:17 UTC 
VERSION = '1.0.0.3'

import os
import sys
import shlex
import traceback
import re

import autoutils
from autoutils import COLOR
from autoutils import OptParser

class autopromiscdetect:

    def __init__(self):

        self.version = VERSION
        self.nopen = autoutils.autoutils()
        self.parser = self.get_arg_parser()
        self.doprint = self.nopen.doprint
        self.doit = self.nopen.doit


    def main(self, argv):

        prog = argv[0]
        argv = argv[1:]
        opts, args = self.nopen.parseArgs(self.parser, argv)

        # connect to autoport after parse args
        if not self.nopen.connected:
            self.nopen.connect()

        if opts.v:
            self.print_version(prog)
            return

        promisc_interfaces = []

        if "Linux 2.4" in self.nopen.nopen_serverinfo: #TESTED
            output, outputlines = self.nopen.doitwrite('ip link show')
            for line in output.split('\n'):
                if 'PROMISC' in line:
                    device = re.split(':',line)[1][1:]
                    promisc_interfaces.append(device)

        elif "Linux 2.6" in self.nopen.nopen_serverinfo: #TESTED
            output, nopenoutput, outputlines = self.doit('ls -1 /sys/class/net/*/flags')
            for line in outputlines:
                output2, nopenoutput2, outputlines2 = self.doit('cat %s' % line)
                try:
                    flag = int(output2, 16)

                    if (flag & 0x100) != 0:
                        device = re.split('/',line)[4]
                        promisc_interfaces.append(device)
                except ValueError:
                    pass

        elif re.search('SunOS 5.(8|9|10)',self.nopen.nopen_serverinfo): #TESTED
             output, nopenoutput, outputlines = self.doit('kstat -s promisc')
             num_interfaces = len(outputlines)/4
             for groupnum in range(0,num_interfaces):
                 iface_array = re.split(' *',outputlines[4*groupnum])
                 device = iface_array[1]+iface_array[3]
                 is_it_promisc = re.split(' *',outputlines[4*groupnum+2])[1]
                 if 'off' not in is_it_promisc and is_it_promisc != '0':
                     promisc_interfaces.append(device)

        elif "FreeBSD" in self.nopen.nopen_serverinfo: #TESTED
            output, nopenoutput, outputlines = self.doit('ifconfig')
            for line in outputlines:
                if 'PROMISC' in line:
                    device = re.split(':',line)[0]
                    promisc_interfaces.append(device)

        else:
            self.doprint(COLOR['fail'],'BAIL: -gs promiscdetect is not supported on this:\n\n%s\n\n' % self.nopen.nopen_serverinfo)
            return self.nopen.finish()

        if promisc_interfaces:
            promisc_interfaces_string = ''
            for interface in promisc_interfaces:
                promisc_interfaces_string += 'WARNING: promiscuous-mode ENABLED for device %s!\n' % interface
            self.nopen.textpopup('-geometry 88x18 -bg white -fg red',promisc_interfaces_string)
        else:
            self.doprint(COLOR['success'],'No devices in promiscuous-mode.')

        return self.nopen.finish()


    def get_arg_parser(self):

        epilog = '\nThis will detect whether or not the NIC is in promiscuous mode.\n'
        epilog += '\n-gs promiscdetect version %s\n' % self.version

        parser = OptParser(usage='usage: -gs promiscdetect [options]', epilog=epilog)
        parser.add_option('-v', dest='v', action='store_true', help='Show version and exit.')

        return parser


    def print_version(self, prog):

        script_name = os.path.basename(prog)

        if script_name.startswith('auto'):
            script_name = script_name.split('auto', 1)[1]

        self.doprint('-gs %s version %s' % (script_name, self.version))


if __name__ == '__main__':

    try:
        # re-set the argv b/c NOPEN will do weird things with splitting args
        argv = shlex.split(' '.join(sys.argv))
        autopromiscdetect().main(argv)
    except Exception, e:
        print '\n\n%sUnhandled python exception: %s%s\n\n' % \
            (COLOR['bad'], str(e), COLOR['normal'])
        print '%sStack trace:\n' % COLOR['fail']
        traceback.print_exc()
        print COLOR['normal']
